package com.remote.ui.controller;

import com.remote.common.command.Commands;
import com.remote.common.constant.Constants;
import com.remote.common.model.ClientInfo;
import com.remote.common.model.Response;
import com.remote.ui.constant.UIConstant;
import com.remote.ui.event.KeyBoardHandler;
import com.remote.ui.event.MouseHandler;
import io.netty.channel.ChannelHandlerContext;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextArea;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;

import java.awt.*;
import java.io.ByteArrayInputStream;
import java.util.Map;

public class ScreenController extends BaseController {


    public Canvas screenImg;

    public Slider definition;
    public Menu adjustDPI;

    @Override
    protected void initView(Scene scene, Map<String, Object> vars) {
        definition.setBlockIncrement(2);
        definition.setValue(Constants.SCREEN_QUALITY);
        this.initMenu(vars);
    }

    private void initMenu(Map<String, Object> vars) {
        ObservableList<MenuItem> dpiItems = adjustDPI.getItems();
        ClientInfo clientInfo = (ClientInfo) vars.get(UIConstant.P_CLIENT_INFO);
        if (clientInfo != null && clientInfo.getSupportableDpi() != null && clientInfo.getSupportableDpi().size() > 0) {
            for (DisplayMode displayMode : clientInfo.getSupportableDpi()) {
                String text = String.format("%sx%s", displayMode.getWidth(), displayMode.getHeight());
                MenuItem menuItem = new MenuItem(text);
                menuItem.setUserData(displayMode);
                menuItem.setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent event) {
                        MenuItem item = (MenuItem) event.getSource();
                        getControllerManager().getCommandContext().fireCommand(clientInfo.getClientId(), Commands.MODIFY_DPI, item.getUserData());
                    }
                });
                dpiItems.add(menuItem);
            }
        }
    }

    @Override
    protected void initEvent(Scene scene, Map<String, Object> vars) {
        final KeyBoardHandler remoteKeyBoardListener = new KeyBoardHandler(this);
        final MouseHandler mouseHandler = new MouseHandler(this);
        scene.setOnKeyPressed(e -> {
            remoteKeyBoardListener.keyPressed(e);
        });
        scene.setOnKeyReleased(e -> {
            remoteKeyBoardListener.keyReleased(e);
        });
        screenImg.setOnMouseClicked(e -> {
            mouseHandler.mouseClicked(e);
        });
        screenImg.setOnMouseDragged(e -> {
            mouseHandler.mouseDragged(e);
        });
        screenImg.setOnMouseMoved(e -> {
            mouseHandler.mouseMoved(e);
        });
        screenImg.setOnMousePressed(e -> {
            mouseHandler.mousePressed(e);
        });
        screenImg.setOnMouseReleased(e -> {
            mouseHandler.mouseReleased(e);
        });
        screenImg.setOnScroll(e -> {
            mouseHandler.mouseWheelMoved(e);
        });


        definition.valueProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                ClientInfo clientId = (ClientInfo) vars.get(UIConstant.P_CLIENT_INFO);
                getControllerManager().getCommandContext().fireCommand(clientId.getClientId(), Commands.QUALITY, newValue.intValue());
            }
        });

    }


    @Override
    protected void onReadDate(ChannelHandlerContext ctx, Object obj) {
        try {
            Response response = (Response) obj;
            if (Boolean.FALSE.equals(response.getIsSucceed())) {
                return;
            }
            switch ((Commands) response.getCommand()) {
                case SCREEN:
                    Image image = new Image(new ByteArrayInputStream((byte[]) response.getValue()));
                    screenImg.setHeight(image.getWidth());
                    screenImg.setWidth(image.getWidth());
                    GraphicsContext graphicsContext2D = screenImg.getGraphicsContext2D();
                    graphicsContext2D.drawImage(image, 0, 0);
                    graphicsContext2D.fill();
                    break;
                case SEND_MESSAGE:
                    String title = String.format("%s向你发送消息", response.getClientId());
                    String message = response.getValue().toString();
                    showMessage(title, message);
                    break;
                default:
                    break;
            }

        } catch (Throwable e) {
            e.printStackTrace();
        }
    }


    public void sendMessage(ActionEvent actionEvent) {
        ClientInfo clientInfo = (ClientInfo) getValue(UIConstant.P_CLIENT_INFO);

        Stage window = new Stage();
        window.setTitle("给" + clientInfo + "发消息");
        //modality要使用Modality.APPLICATION_MODEL
        window.initModality(Modality.APPLICATION_MODAL);
        window.setMinWidth(200);
        window.setMinHeight(100);
        TextArea label = new TextArea();
        Button button = new Button("发送");
        button.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                getControllerManager().getCommandContext().fireCommand(clientInfo.getClientId(), Commands.SEND_MESSAGE, label.getText());
                window.close();
            }
        });

        VBox layout = new VBox(20);
        layout.getChildren().addAll(label, button);
        layout.setAlignment(Pos.CENTER);
        Scene scene = new Scene(layout);
        window.setScene(scene);
        window.showAndWait();
    }
}
